#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QString>
#include <QList>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //    // 一个信号绑定多个槽函数
    //    connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::slot_fun1);
    //    connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::slot_fun2);

    //多个信号绑定一个槽函数
    //    connect(ui->btn_2, &QPushButton::clicked, this, &MainWindow::slot_fun1);
    //    connect(ui->btn_2, &QPushButton::clicked, this, &MainWindow::slot_fun2);


    //    connect(ui->btn_2, &QPushButton::clicked, this, &MainWindow::slot_fun2);
    //     //一个控件可以连接到另外一个控件的信号上
    //    connect(ui->pushButton, &QPushButton::clicked, ui->btn_2, &QPushButton::clicked);


    //给按钮2绑定一个抽屉槽函数
    //    ui->btn_2->setCheckable(true);
    //    connect(ui->btn_2, &QPushButton::clicked, this, &MainWindow::on_btn_2_toggled);


    //断开信号和槽的连接
    //    disconnect(ui->btn_2, 0, 0, 0);
    //    ui->btn_2->disconnect();

    //断开指定的信号
    //    disconnect(ui->btn_2, &QPushButton::toggled, 0, 0);
    //    disconnect(ui->btn_2, &QPushButton::clicked, 0, 0);

    //断开指定对象的所有槽函数
    //    disconnect(ui->btn_2, 0, this, 0);
    //    ui->btn_2->disconnect(this);
    //    ui->btn_2->disconnect(this, nullptr);

    //断开指定对象的某个槽函数
    //    disconnect(ui->btn_2, nullptr, this, SLOT(&MainWindow::on_btn_2_toggled));
    //    ui->btn_2->disconnect(this, SLOT(&MainWindow::on_btn_2_toggled));



    //    disconnect(ui->btn_2, &QPushButton::clicked, this, &MainWindow::on_btn_2_toggled);
    //    ui->btn_2->disconnect(SIGNAL(&QPushButton::clicked), this, SLOT(&MainWindow::on_btn_2_toggled));


    //写法错误
    //    disconnect(ui->btn_2, 0, this, &MainWindow::on_btn_2_toggled);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::slot_fun1()
{
    qDebug() << "slot_fun1" << endl;
}

void MainWindow::slot_fun2()
{
    qDebug() << "slot_fun2" << endl;
    ui->plainTextEdit->appendPlainText("aaaa");
}


void MainWindow::on_btn_2_toggled(bool checked)
{
    qDebug() << "on_btn_2_toggled: " << checked << endl;
}

void MainWindow::on_pushButton_2_clicked()
{
    //QList的相关函数
    qDebug() << "on_pushButton_2_clicked" << endl;

    //在栈上创建对象
    QList<QString> list;

    //在堆上创建对象
    //    QList<QString>* list_p = new QList<QString>();

    list << "aa" << "bb" ;


    for (int i = 0; i < list.size(); ++i) {
        qDebug() << "list[i]: " << list[i] << endl;
    }

    list[0] = "AA";

    list.replace(1, "BB");

    foreach (auto str , list) {
        qDebug() << "str: " << str << endl;
    }

    list.append("cc");

    //编译报警告，因为swap不推荐使用，已经被弃用
    //    list.swap(1,2);
    //推荐使用swapItemsAt，和swap效果一样
    list.swapItemsAt(1, 2);

    foreach (auto str , list) {
        qDebug() << "str: " << str << endl;
    }

    bool r =  list.contains("CC");
    qDebug() << "r: " << r << endl;
    r =  list.contains("cc");
    qDebug() << "r: " << r << endl;

    int i = list.indexOf("BB");
    qDebug() << "i: " << i << endl;
    i = list.indexOf("CC");
    qDebug() << "i: " << i << endl;


}


void MainWindow::on_pushButton_3_clicked()
{
    qDebug() << "on_pushButton_3_clicked" << endl;

    QMap<QString, int> map;
    map["one"] = 1;
    map["three"] = 3;
    map.insert("five", 5);

    int value =  map["six"];
    qDebug() << "value: " << value << endl;
    qDebug() << "isContain: " << map.contains("six") << endl;

    value =  map.value("seven");
    qDebug() << "value: " << value << endl;
    qDebug() << "isContain: " << map.contains("seven") << endl;

    value =  map.value("seven", 10);
    qDebug() << "value: " << value << endl;

    map.insert("seven", 7);
    value = map.value("seven", 10);
    qDebug() << "value: " << value << endl;

    //insert在插入数据时，如果键已经存在，就回用新值替换旧值
    map.insert("seven", 17);

    QList<int> list =  map.values("seven");
    foreach (auto a, list) {
        qDebug() << "a: " << a << endl;
    }

    map.insertMulti("seven" , 27);

    list =  map.values("seven");
    foreach (auto b, list) {
        qDebug() << "b: " << b << endl;
    }

    QMultiMap<QString, int> multMap, multMap2, multMap3;
    multMap.insert("one", 1);
    multMap.insert("one", 11);
    multMap.insert("one", 111);

    list =  multMap.values("one");
    foreach (auto c, list) {
        qDebug() << "c: " << c << endl;
    }

    multMap2.insert("one", 1111);

    multMap3 = multMap + multMap2;
    list =  multMap3.values("one");
    foreach (auto d, list) {
        qDebug() << "d: " << d << endl;
    }

    //Java风格的迭代器
    QListIterator<int> it(list);
    while(it.hasNext()){
        //next获取当前游标所在位置的元素，并将游标移动到下一个元素处
        qDebug() << "next: " << it.next() << endl;

    }

    //此时游标已经移动到list的末尾，如果继续取数据，越界访问，数据不确定
    //    qDebug() << "next: " << it.next() << endl;


    //如果迭代器的游标在第一个元素处，就不能往前获取数据，否则会野指针
    //    qDebug() << "Previous: " << it.previous() << endl;

    //    while(it.hasPrevious()){
    //        //Previous获取当前游标所在位置的元素，并将游标移动到前一个元素处
    //         qDebug() << "Previous: " << it.previous() << endl;

    //    }

    //c++风格的迭代器
    for (QList<int>::iterator it =  list.begin(); it != list.end(); it++) {
        *it += 10;
        qDebug() << "*it: " << *it << endl;
    }

    QList<int>::const_iterator it2 =  list.constBegin();
    //    *it2 = 2222;
    qDebug() << "*it2: " << *it2 << endl;
}

void MainWindow::on_pushButton_4_clicked()
{
    QStringList list;
    list<<"one"<<"two"<<"three"<<"four";

    qDebug() << QObject::tr("std: copy算法： ");
    QVector<QString> vect(4);
    //将list中的4个字符串拷贝到vect中
    std::copy(list.begin(), list.end(), vect.begin());

    qDebug() << list;
    qDebug() << vect;

    qDebug() << QObject::tr("std: equal算法： ");

    bool ret1 =  std::equal(list.begin(), list.end(), vect.begin());
    qDebug() << ret1;

    qDebug() << QObject::tr("std: fill算法： ");
    std::fill(list.begin(), list.end(), "five");
    qDebug() << list;

    QList<int> list2;
    list2<<3 << 3<<6<<6<<6<<7;
    int count =  std::count(list2.begin(), list2.end(), 6);
    qDebug() << "count: " << count;

    //查找算法: lower_bound函数在查找指定元素时，容器中的元素必须从小到大有序
    QList<int>::iterator it = std::lower_bound(list2.begin(), list2.end(), 6);
    qDebug() << "it: " << *it << count;
    list2.insert(it, 160);
    qDebug() << list2;

    QList<int> list3;
    list3<<100<< 82<<30<<56<<78<<20<<10;
    qDebug() << list3;
    //排序
    std::stable_sort(list3.begin(), list3.end());
    qDebug() << list3;

    //qSort从大到小排序---被弃用了，推荐使用std::sort
    //    qSort(list3.begin(), list3.end(), std::greater<int>());
    std::sort(list3.begin(), list3.end(), std::greater<int>());

    qDebug() << list3;

    //swap实现两个变量数据的交换
    double x = 123.45;
    double y = 45.123;
    qDebug()  << "x: " << x << "y: "<< y<<endl;
    std::swap(x, y);
    qDebug()  << "x: " << x << "y: "<< y<<endl;

}

void MainWindow::on_pushButton_5_clicked()
{
    QString str = "hello";
    qDebug()  << "str.size: " << str.size() <<endl;

    str[0] = QChar('A');
    qDebug()  << str;
    str[1] = 'B';
    qDebug()  << str;

    str.append("QT");
    str.append('W');
    qDebug()  << str;

    //从指定下标位置开始，替换指定数量的字符为新的字符串
    str.replace(2, 4, "yueqian");
    qDebug() << str;
    //在指定位置插入字符串
    str.insert(2, "ok");
    qDebug() << str;

    //字符串拼接字符串
    str += "!!!";
    qDebug() << str;
    /*
     * windows端的换行符： \r\n
     * Linux系统换行符：\n
     * MacOS X之前换行符 \r, 之后时\n
     */


    str = "  a hi\r\n  QT!   ";
    qDebug() << str;
    QString s =  str.trimmed();

    qDebug() << str;
    qDebug() << s;
    //去除字符串两端和中间的空白字符(\r, \n, ' ' )
    s =  str.simplified();
    qDebug() << str;
    qDebug() << s;

    str = "hi.my.,QT";
    QStringList slist =  str.split(".", QString::SkipEmptyParts);
    qDebug() << slist;
    str = slist.join(" ");
    qDebug() << str;

    qDebug() << str.isEmpty();
    qDebug() << str.isNull();

    str = " ";
    qDebug() << str.isEmpty();
    qDebug() << str.isNull();

    str = "";
    qDebug() << str.isEmpty();
    qDebug() << str.isNull();

    qDebug() << QString().isEmpty();
    qDebug() << QString().isNull();

    //字符串的查询
    qDebug() << "---------------" << endl;
    QString str2 = "helloyueqianworld";
    QString rstr =  str2.right(5);
    qDebug() << str2;
    qDebug() << rstr;

    rstr =  str2.left(5);
    qDebug() << rstr;
    rstr =  str2.mid(5, 8);
    qDebug() << rstr;

    QChar c =  str2.at(6);
    qDebug() << c;

    int n = str2.count('l');
    qDebug() << n;
    n = str2.count("o");
    qDebug() << n;

    //以x开头
    bool b =    str2.startsWith('h');
    qDebug() << b;
    b =    str2.startsWith("Hello");
    qDebug() << b;

    //以x结尾
    b =    str2.endsWith("world");
    qDebug() << b;
    //包含指定的字符串
    b =    str2.contains("World");
    qDebug() << b;


    qDebug() << "---------------" << endl;
    //字符串转换函数
    QString str3 = "12345";
    //toInt将字符串转换成整数
    int num =  str3.toInt();
    qDebug() << num;

    //将数字转换成字符串
    QString str4 =  QString::number(num);
    qDebug() << str4;

    str3 = "FF";
    bool ok;
    num = str3.toInt(&ok, 16);
    qDebug() << num << "ok: " <<ok;

    //    str3 = "FFY";
    //    num = str3.toInt(&ok, 16);
    //    qDebug() << num << "ok: " <<ok;

    str4 =  QString::number(num, 16);
    qDebug() << str4;

    str3 = "67.89";
    float f =  str3.toFloat(&ok);
    qDebug() << f << "ok: " << ok ;

    str3 = "67.89abc";
    f =  str3.toFloat(&ok);
    qDebug() << f << "ok: " << ok ;

    str3 = "HelloWorld";
    str4 =  str3.toUpper();
    qDebug() << str4;
    str4 =  str3.toLower();
    qDebug() << str4;
    qDebug() << str3;

    int age = 25;
    QString name = "zhangsan";

    str4 = QString("name is %1, age is %2").arg(name).arg(age);
    qDebug() << str4;


}


void MainWindow::on_pushButton_6_clicked()
{
    QVariant v1(15);
    qDebug() << v1.toInt();
    QVariant v2(123.456);
    qDebug() << v2.toDouble();
    QVariant v3("hello yueqian qian");
    qDebug() << v3.toString();

    QColor color = QColor(Qt::red);
    QVariant v4 = color;
    qDebug() << v4.type();
    qDebug() <<  v4.value<QColor>();

    QString str = "Hello";
    QVariant v5 = str;
    qDebug() <<  v5.type();
    qDebug() << v5.canConvert(QVariant::Int);
    qDebug() << v5.toInt();
    qDebug() <<v5.toString();
    qDebug() << v5.convert(QVariant::Int);

    qDebug() << "-------------" <<endl;

    QByteArray arr(4, 'A');
    qDebug() << arr;
    std::string s =  arr.toStdString();
    qDebug() << s.length();

    QByteArray arr2("helloworld");
    qDebug() << arr2;
    qDebug() << arr2.length();

    //QByteArray字节数组，它的函数功能和QString一样的，因为字符串本就是一个连续的字符序列(字符数组)

}



















